package mini;

import java.util.HashMap;

import mini.expr.Element;
import mini.oo.MiniClassDefinition;

/**
 * An environment encapsulates a symbol table and a function table
 * @author Jennifer
 *
 */
public class Env {

	private HashMap<String,Element> nametable = new HashMap<String,Element>();
	private HashMap<String,Proc> functable = new HashMap<String,Proc>();
	private HashMap<String,MiniClassDefinition> classtable = new HashMap<String,MiniClassDefinition>();
	
	public Env() {
		nametable = new HashMap<String,Element>();
		functable = new HashMap<String,Proc>();
		classtable = new HashMap<String,MiniClassDefinition>();
	}
	
	public Env( HashMap<String,Element> hm, HashMap<String,Proc> ft, HashMap<String,MiniClassDefinition> ct ) {
		setNametable(hm);
		setFunctable(ft);
		setClasstable(ct);
	}
	
	public HashMap<String, MiniClassDefinition> getClasstable() {
		return classtable;
	}
	public void setClasstable(HashMap<String, MiniClassDefinition> classtable) {
		this.classtable = classtable;
	}
	public HashMap<String, Element> getNametable() {
		return nametable;
	}
	public void setNametable(HashMap<String, Element> nametable) {
		this.nametable = nametable;
	}
	public HashMap<String, Proc> getFunctable() {
		return functable;
	}
	public void setFunctable(HashMap<String, Proc> functable) {
		this.functable = functable;
	}

	/**
	 * This adds something to the nametable for this environment
	 * @param name
	 * @param theClass
	 */
	public void addToNametable(String next, Element eval) {
		if( nametable == null ) {
			nametable = new HashMap<String,Element>();
		}
		nametable.put(next,eval);
	}

	/**
	 * This adds something to the functiontable for this environment
	 * @param name
	 * @param theClass
	 */
	public void addToFunctiontable(String name, Proc proc) {
		if( functable == null ) {
			functable = new HashMap<String,Proc>();
		}
		functable.put(name,proc);
	}

	/**
	 * This adds something to the class table for this environment
	 * @param name
	 * @param theClass
	 */
	public void addToClasstable(String name, MiniClassDefinition theClass) {
		if( classtable == null ) {
			classtable = new HashMap<String,MiniClassDefinition>();
		}
		classtable.put(name,theClass);
	}

	/**
	 * Like adding it to the nametable, but it only sets the
	 * value if it's there already. If it's not there, then
	 * it doesn't do anything.
	 * 
	 * @param name The name
	 * @param elem What to updat withe
	 * @return True if it was there before and updated, or
	 * false otherwise
	 */
	public boolean updateInNametable(String name, Element elem) {
		if( nametable != null && nametable.containsKey(name)) {
			nametable.put(name, elem);
			return true;
		}
		return false;
	}
	
}
